// WebCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "WebCtrl.h"
#include <ATLBASE.H>
#include <Mshtml.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CWebCtrl

CWebCtrl::CWebCtrl():m_pExternal(NULL),m_pBrowserApp(NULL)
{
	EnableAutomation();
}

CWebCtrl::~CWebCtrl()
{
	if (m_pExternal)
	{
		m_pExternal->Release();
	}
	if (m_pBrowserApp)
	{
		m_pBrowserApp->Release();
	}
}

void CWebCtrl::OnFinalRelease()
{
	// When the last reference for an automation object is released
	// OnFinalRelease is called.  The base class will automatically
	// deletes the object.  Add additional cleanup required for your
	// object before calling the base class.

	CWnd::OnFinalRelease();
}


BEGIN_MESSAGE_MAP(CWebCtrl, CWnd)
	//{{AFX_MSG_MAP(CWebCtrl)
	ON_WM_CREATE()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BEGIN_EVENTSINK_MAP(CWebCtrl, CWnd)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 102 /* StatusTextChange */, OnStatusTextChange, VTS_BSTR)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 108 /* ProgressChange */, OnProgressChange, VTS_I4 VTS_I4)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 105 /* CommandStateChange */, OnCommandStateChange, VTS_I4 VTS_BOOL)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 106 /* DownloadBegin */, OnDownloadBegin, VTS_NONE)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 104 /* DownloadComplete */, OnDownloadComplete, VTS_NONE)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 113 /* TitleChange */, OnTitleChange, VTS_BSTR)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 252 /* NavigateComplete2 */, NavigateComplete2, VTS_DISPATCH VTS_PVARIANT)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 250 /* BeforeNavigate2 */, BeforeNavigate2, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 112 /* PropertyChange */, OnPropertyChange, VTS_BSTR)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 251 /* NewWindow2 */, OnNewWindow2, VTS_PDISPATCH VTS_PBOOL)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 259 /* DocumentComplete */, DocumentComplete, VTS_DISPATCH VTS_PVARIANT)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 253 /* OnQuit */, OnQuit, VTS_NONE)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 254 /* OnVisible */, OnVisible, VTS_BOOL)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 255 /* OnToolBar */, OnToolBar, VTS_BOOL)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 256 /* OnMenuBar */, OnMenuBar, VTS_BOOL)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 257 /* OnStatusBar */, OnStatusBar, VTS_BOOL)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 258 /* OnFullScreen */, OnFullScreen, VTS_BOOL)
	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 260 /* OnTheaterMode */, OnTheaterMode, VTS_BOOL)

	ON_EVENT(CWebCtrl, AFX_IDW_PANE_FIRST, 271, NavigateError, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
END_EVENTSINK_MAP()

BEGIN_DISPATCH_MAP(CWebCtrl, CWnd)
	//{{AFX_DISPATCH_MAP(CWebCtrl)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()

// Note: we add support for IID_IWebCtrl to support typesafe binding
//  from VBA.  This IID must match the GUID that is attached to the 
//  dispinterface in the .ODL file.

// {F0A6E522-287F-413D-9E8D-70EB425201EF}
static const IID IID_IWebCtrl =
{ 0xf0a6e522, 0x287f, 0x413d, { 0x9e, 0x8d, 0x70, 0xeb, 0x42, 0x52, 0x1, 0xef } };

BEGIN_INTERFACE_MAP(CWebCtrl, CWnd)
	INTERFACE_PART(CWebCtrl, IID_IWebCtrl, Dispatch)
END_INTERFACE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWebCtrl message handlers

int CWebCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	RECT rectClient;
	GetClientRect(&rectClient);
	if (!m_wndHTML.CreateControl(CLSID_WebBrowser, lpCreateStruct->lpszName,
		WS_VISIBLE | WS_CHILD, rectClient, this, AFX_IDW_PANE_FIRST))
	{
		DestroyWindow();
		return FALSE;
	}
	
	LPUNKNOWN lpUnk = m_wndHTML.GetControlUnknown();
	HRESULT hr = lpUnk->QueryInterface(IID_IWebBrowser2, (void**) &m_pBrowserApp);
	if (!SUCCEEDED(hr))
	{
		m_pBrowserApp = NULL;
		m_wndHTML.DestroyWindow();
		DestroyWindow();
		return FALSE;
	}
	CComQIPtr<IConnectionPointContainer> spContainer(m_pBrowserApp);
	if (!spContainer)
	{
		return 0;
	}
	CComQIPtr<IConnectionPoint> spConnectionPoint;
	spContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &spConnectionPoint);
	DWORD m_dwCookie;
	spConnectionPoint->Advise(this->GetIDispatch(TRUE), &m_dwCookie);
//  
//  	m_pBrowserApp->Navigate2(COleVariant(_T("about:blank")),COleVariant((long)0),
//  		COleVariant(_T("")),NULL,COleVariant(_T("")));
// 
// 	CComQIPtr<IDispatch> pDisp;
// 	m_pBrowserApp->get_Document(&pDisp);
// 	CComQIPtr<IHTMLDocument2> pDoc;
// 	pDisp->QueryInterface(IID_IHTMLDocument2,(PVOID*)&pDoc);
// 	CComQIPtr<ICustomDoc> pCDoc;
// 	pDoc->QueryInterface(IID_ICustomDoc,(PVOID*)&pCDoc);
// 	pCDoc->SetUIHandler((IDocHostUIHandler*)this);
	
	return 0;
}
long __stdcall CWebCtrl::GetExternal( IDispatch __RPC_FAR *__RPC_FAR *ppDispatch )
{
	if (m_pExternal)
	{
		*ppDispatch = m_pExternal;
		m_pExternal->AddRef();
		return S_OK;
	}
	return E_NOTIMPL;
}
VOID CWebCtrl::SetExternal( IDispatch* pExternal )
{
	if (m_pExternal)
	{
		m_pExternal->Release();
	}
	m_pExternal = pExternal;
	pExternal->AddRef();
}
void CWebCtrl::BeforeNavigate2( LPDISPATCH pDisp, VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers, BOOL* Cancel )
{

}
void CWebCtrl::NavigateComplete2( LPDISPATCH pDisp, VARIANT* URL )
{
	
}
void CWebCtrl::DocumentComplete( LPDISPATCH pDisp, VARIANT* URL )
{

}
void CWebCtrl::OnStatusTextChange( LPCTSTR lpszText )
{
	
}
void CWebCtrl::OnProgressChange( long nProgress, long nProgressMax )
{
	
}
void CWebCtrl::OnCommandStateChange( long nCommand, BOOL bEnable )
{
	
}
void CWebCtrl::OnDownloadBegin()
{
	
}
void CWebCtrl::OnTitleChange( LPCTSTR lpszText )
{
	
}
void CWebCtrl::OnTheaterMode( BOOL bTheaterMode )
{
	
}
void CWebCtrl::OnFullScreen( BOOL bFullScreen )
{
	
}
void CWebCtrl::OnStatusBar( BOOL bStatusBar )
{
	
}
void CWebCtrl::OnMenuBar( BOOL bMenuBar )
{
	
}
void CWebCtrl::OnToolBar( BOOL bToolBar )
{
	
}
void CWebCtrl::OnVisible( BOOL bVisible )
{
	
}
void CWebCtrl::OnQuit()
{
	
}
void CWebCtrl::OnDocumentComplete( LPCTSTR lpszURL )
{
	
}
void CWebCtrl::OnNewWindow2( LPDISPATCH* ppDisp, BOOL* Cancel )
{
	
}
void CWebCtrl::OnPropertyChange( LPCTSTR lpszProperty )
{
	
}
void CWebCtrl::OnDownloadComplete()
{
	
}

IWebBrowser2* CWebCtrl::GetWebBrowser() const
{
	return m_pBrowserApp;
}

void CWebCtrl::OnSize( UINT nType, int cx, int cy )
{
	CWnd::OnSize(nType, cx, cy);

	if (::IsWindow(m_wndHTML.m_hWnd))
	{
		// need to push non-client borders out of the client area
		CRect rect;
		GetClientRect(rect);
		::AdjustWindowRectEx(rect,
			m_wndHTML.GetStyle(), FALSE, WS_EX_CLIENTEDGE);
		m_wndHTML.SetWindowPos(NULL, rect.left, rect.top,
			rect.Width(), rect.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
	}
}

void CWebCtrl::NavigateError( LPDISPATCH pDisp, VARIANT* pvURL, VARIANT* pvFrame, VARIANT* pvStatusCode, VARIANT_BOOL* pvbCancel )
{
	UNUSED_ALWAYS(pDisp);
	ASSERT(pvURL != NULL);
	ASSERT(pvFrame != NULL);
	ASSERT(pvStatusCode != NULL);
	ASSERT(pvbCancel != NULL);
	ASSERT(V_VT(pvURL) == VT_BSTR);
	ASSERT(V_VT(pvFrame) == VT_BSTR);
	
	CString strURL(V_BSTR(pvURL));
	CString strFrame(V_BSTR(pvFrame));
	DWORD dwError = V_I4(pvStatusCode);
	
	BOOL bCancel = FALSE;
	// notify the user's class
	OnNavigateError(strURL, strFrame, dwError, &bCancel);
	
	if (pvbCancel)
		*pvbCancel = bCancel ? AFX_OLE_TRUE : AFX_OLE_FALSE;

}

void CWebCtrl::OnNavigateError( LPCTSTR lpszURL, LPCTSTR lpszFrame, DWORD dwError, BOOL *pbCancel )
{
	// default to continuing
	*pbCancel = FALSE;

	// user will override to handle this notification
	UNUSED_ALWAYS(lpszURL);
	UNUSED_ALWAYS(lpszFrame);
}

void CWebCtrl::NavigateEx( LPCTSTR lpszUrl )
{
	GetWebBrowser()->Navigate2(COleVariant(lpszUrl),COleVariant((long)0),
		COleVariant(_T("")),NULL,COleVariant(_T("")));
}